let oneInputCb = null;
var vm = new Vue({
  el: "#app",
  data: {
    loading: false,
    params: {
      design: true,
    },
    userId: 0,
    tabbarIndex: 0,
    currProj: null,
    projs: [],
    configs: [],
    oneInput: {
      show: false,
      title: "",
      label: "",
      placeholder: "",
      value: "",
    },
    controlEdit: {
      show: false,
      title: "",
      needDatasource: false,
      datasourceTips: "",
      form: {
        proj_id: 0,
        rule: "",
        control_type: "",
        label: "",
        tips: "",
        placeholder: "",
        cat_name: "",
        data_source: "",
      },
    },
    onePicker: {
      show: false,
      title: "",
      columns: "",
      value: "",
    },
    menu: {
      show: false,
      type: "change-status",
      data: null,
      actions: [],
    },
  },
  mounted: function () {
    let that = this;
    if (window.location.search?.includes("username")) {
      // let arr=window.location.search.replace('?',"").split('&');
      let url = new URL(window.location.href);
      const params = url.searchParams;
      const design = params.get("design") == "1";
      this.params = {
        design,
        username: params.get("username"),
        password: params.get("password"),
        pid: parseInt(params.get("pid") || 0),
      };
      if (!design) {
        this.tabbarIndex = 1;
      }
      that.init();
    } else {
      that.init();
    }
  },
  methods: {
    ...popu,
    bindTextareaEvent() {
      setTimeout(function () {
        let a = document.querySelectorAll(".mytextarea");
        a.forEach((n) => {
          n.style.height = `${n.scrollHeight}px`;
          n.addEventListener("input", function () {
            this.style.height = `${this.scrollHeight}px`;
          });
        });
      }, 300);
    },
    async init() {
      let loginOK = false;
      if (this.params.username && this.params.password) {
        loginOK = await dalUser.login(
          this.params.username,
          this.params.password
        );
        loginOK = loginOK.msg == "ok";
      } else {
        loginOK = await dalUser.refreshToken();
      }
      $("#toploading").hide();
      if (!loginOK) {
        window.location.href = "./login.html";
      } else {
        this.showOk("登录成功！");
        this.isLogin = true;
        this.userId = store.get("userid");
        await this.loadProjList();
        await this.loadConfigList();
        this.formatConfig();
      }
    },
    onTabbarChange(e) {
      this.bindTextareaEvent();
      // this.loadProjList();
    },
    formatConfig() {
      let projs = JSON.parse(JSON.stringify(this.projs));
      let configs = JSON.parse(JSON.stringify(this.configs));
      projs.forEach((t) => {
        let myconfigs = configs.filter((c) => c.proj_id == t.id);
        if (myconfigs.length == 0) {
          myconfigs.cats = [];
          return;
        }
        let catNames = [];
        myconfigs
          .sort((t1, t2) => t1.sort_id - t2.sort_id)
          .forEach((c) => {
            try {
              if (c.value) {
                c.value = JSON.parse(c.value).v;
              }
            } catch {}
            c.show = false;
            c.showValue = "";
            if (c.data_source) {
              try {
                c.data_source = JSON.parse(c.data_source);
                if (c.control_type == "checkbox") {
                  if (!c.value) {
                    c.value = [];
                  }
                } else if (c.control_type == "picker") {
                  if (c.value) {
                    let tmp = c.data_source.find((d) => d.value == c.value);
                    if (tmp && tmp.text) {
                      c.showValue = tmp.text;
                    }
                  }
                }
              } catch (e) {
                console.log(e);
              }
            }
            let i = catNames.findIndex((t) => t.cat_name == c.cat_name);
            if (i > -1) {
              catNames[i].configs.push(c);
            } else {
              catNames.push({
                cat_name: c.cat_name,
                configs: [c],
              });
            }
          });
        t.cats = catNames;
      });
      this.projs = projs;
      let currProj = this.currProj;
      if (this.params.pid) {
        currProj = { id: this.params.pid };
      }
      if (!currProj) {
        let lastCurrProjId = store.get("lastCurrProjId");
        if (lastCurrProjId) {
          currProj = projs.find((t) => t.id == lastCurrProjId);
        }
      } else {
        currProj = projs.find((t) => t.id == currProj.id);
      }
      if (!currProj) {
        currProj = projs[0];
      }
      this.currProj = currProj;
    },
    async loadProjList() {
      this.loading = true;
      let res = await dalProj.list();
      this.loading = false;
      if (res.msg == "ok" && res.data) {
        this.projs = res.data;
      } else {
        this.alert(res.msg);
      }
    },
    async addProj() {
      this.loading = true;
      let title = await this.startOneInut(
        "添加项目(1/2)",
        "名称",
        "如：小程序系统"
      );
      await sleep(500);
      let callback_url = await this.startOneInut(
        "添加项目(2/2)",
        "回调地址",
        "如：http://a.com/notify"
      );
      let res = await dalProj.insert(title, callback_url);
      this.loading = false;
      if (res.msg != "ok") {
        return this.showFail(res.msg);
      }
      this.showOk("添加项目成功!");
      await this.loadProjList();
      this.formatConfig();
    },
    async updateProj(item) {
      this.loading = true;
      let title = await this.startOneInut(
        "修改项目(1/2)",
        "名称",
        "",
        item.title
      );
      await sleep(500);
      let callback_url = await this.startOneInut(
        "添加项目(2/2)",
        "回调地址",
        "如：http://a.com/notify",
        item.callback_url
      );
      let res = await dalProj.update({ title, callback_url }, item.id);
      this.loading = false;
      if (res.msg != "ok") {
        return this.showFail(res.msg);
      }
      this.showOk("修改项目成功!");
      await this.loadProjList();
      this.formatConfig();
    },
    async delProj(item) {
      this.loading = true;
      //先删除所有config
      if (item.cats.configs && item.cats.configs.length > 0) {
        for (let t of item.cats.configs) {
          await dalConfig.del(t.id);
        }
      }
      let res = await dalProj.del(item.id);
      this.loading = false;
      if (res.msg != "ok") {
        return this.showFail(res.msg);
      }
      this.showOk("删除项目成功!");
      await this.loadProjList();
      this.formatConfig();
    },
    async loadConfigList() {
      this.loading = true;
      let res = await dalConfig.list();
      this.loading = false;
      if (res.msg == "ok" && res.data) {
        this.configs = res.data;
      } else {
        this.alert(res.msg);
      }
    },
    async addConfigRow() {
      let controlItem = await this.startOnePicker(
        "请选择控件类型",
        controls,
        0
      );
      if (!controlItem) {
        return;
      }
      this.controlEdit.form.proj_id = this.currProj.id;
      this.controlEdit.form.user_id = this.userId;
      this.controlEdit.form.control_type = controlItem.control_type;
      this.controlEdit.show = true;
      this.controlEdit.needDatasource = controlItem.needDatasource;
      this.controlEdit.datasourceTips = controlItem.datasourceTips;
      this.bindTextareaEvent();
    },
    async updateConfigRow(item) {
      console.log("updateConfigRow", item);
      item = JSON.parse(JSON.stringify(item));
      if (typeof item.data_source == "object") {
        item.data_source = JSON.stringify(item.data_source);
      }
      let index = controls.findIndex(
        (t) => t.control_type == item.control_type
      );
      let controlItem = await this.startOnePicker(
        "请选择控件类型",
        controls,
        index
      );
      if (!controlItem) {
        return;
      }
      item.control_type = controlItem.control_type;
      this.controlEdit.form = item;
      this.controlEdit.show = true;
      this.controlEdit.needDatasource = controlItem.needDatasource;
      this.controlEdit.datasourceTips = controlItem.datasourceTips;
      this.bindTextareaEvent();
    },
    onFormatJSON() {
      let tmp = this.controlEdit.form.data_source;
      if (tmp) {
        try {
          tmp = eval("(" + tmp + ")");
          console.log(tmp);
          tmp = JSON.stringify(tmp);
        } catch (e) {
          console.log(e);
          this.showFail("格式有误");
          return false;
        }
      }
      this.controlEdit.form.data_source = tmp;
      return true;
    },
    async onStartSelectCat() {
      let columns = this.currProj.cats?.map((t) => {
        return {
          label: t.cat_name,
          value: t.cat_name,
        };
      });
      if (!columns || columns.length == 0) {
        return this.notify("danger", "暂无分类");
      }
      let controlItem = await this.startOnePicker("请选择分类", columns, 0);
      if (!controlItem) {
        return;
      }
      this.controlEdit.form.cat_name = controlItem.label;
    },
    async onStartSelectRule() {
      let controlItem = await this.startOnePicker(
        "请选择校验规则",
        validatorRules,
        0
      );
      if (!controlItem) {
        return;
      }
      this.controlEdit.form.rule = controlItem.label;
    },
    async onControlEditSubmit() {
      let form = this.controlEdit.form;
      if (!form.label) {
        return this.showFail("名称不能为空");
      }
      if (!form.cat_name) {
        return this.showFail("分类不能为空");
      }
      if (!form.label) {
        return this.showFail("名称不能为空");
      }
      if (!this.onFormatJSON()) {
        return;
      }
      this.showLoading(true);
      form.sort_id = form.sort_id || 1;
      let res;
      delete form.show;
      delete form.showValue;
      if (form.id) {
        res = await dalConfig.update(form, form.id);
      } else {
        let cat = this.currProj.cats.find((c) => c.cat_name == form.cat_name);
        if (cat && cat.configs) {
          form.sort_id = cat.configs.length;
        }
        res = await dalConfig.insert(form);
      }
      this.showLoading(false);
      if (res.msg != "ok") {
        this.alert(res.msg);
      }
      this.showOk("保存成功");
      await this.loadConfigList();
      this.formatConfig();
      this.controlEdit.form = {
        control_type: "",
        label: "",
        tips: "",
        placeholder: "",
        cat_name: form.cat_name,
        data_source: "",
      };
    },
    async delConfig(id) {
      this.loading = true;
      this.showLoading(true);
      let res = await dalConfig.del(id);
      this.showLoading(false);
      this.loading = false;
      if (res.msg != "ok") {
        this.alert(re.msg);
      }
      this.showOk("删除成功");
      await this.loadConfigList();
      this.formatConfig();
    },
    startOneInut(title, label, placeholder, value) {
      return new Promise((ok) => {
        this.oneInput = {
          show: true,
          title,
          label,
          placeholder,
          value,
        };
        oneInputCb = ok;
      });
    },
    onOneInputCancel() {
      oneInputCb(null);
    },
    onOneInputSubmit() {
      this.oneInput.show = false;
      console.log("这里");
      oneInputCb(this.oneInput.value);
    },
    startOnePicker(title, columns, index) {
      return new Promise((ok) => {
        this.onePicker = {
          show: true,
          title,
          columns,
          value: index,
        };
        oneInputCb = ok;
      });
    },
    onOnePickerConfirm(item, i) {
      console.log({ item, i });
      oneInputCb(item);
      this.onePicker.show = false;
    },
    showDetail(title, entity) {
      let arr = [];
      Object.keys(entity).forEach((k) => {
        let v = entity[k];
        if (v === null || v === undefined || v === "") return;
        if (k == "created_at") {
          v = moment(v).format("MM-DD HH:mm");
        } else if (Array.isArray(v)) {
          v = `Array[${Object.keys(v).length}]`;
        } else if (typeof v == "object") {
          v = `(${Object.keys(v).length} items)`;
        }
        if (v.length > 30) {
          arr.push(
            `<div class="alert-line alert-line2"><div>${k}:</div><font>${v}</font></div>`
          );
        } else {
          arr.push(
            `<div class="alert-line"><span>${k}:</span><label>${v}</label></div>`
          );
        }
      });
      let message = arr.join("");
      this.$dialog.alert({
        title,
        message,
      });
    },
    onShowMenu(data, type) {
      let actions;
      if (type == "proj-action") {
        actions = [
          { name: "选中", status: "curr" },
          { name: "查看", status: "detail" },
          { name: "修改", status: "update" },
          { name: "删除", status: "del" },
        ];
      } else if (type == "config-action") {
        actions = [
          { name: "查看", status: "detail" },
          { name: "修改", status: "update" },
          { name: "上移", status: "up" },
          { name: "下移", status: "down" },
          { name: "删除", status: "del" },
        ];
      }
      this.menu = {
        show: true,
        type: type,
        data,
        actions,
      };
    },
    async onMenuSelect(item) {
      let d = this.menu;
      this.menu.show = false;
      console.log({ item });
      if (d.type == "proj-action") {
        if (item.status == "detail") {
          let entity = clone(d.data);
          entity["查询API"] = apiUrl + "?token=" + entity.api_token;
          return this.showDetail("详情:" + d.data.title, entity);
        } else if (item.status == "curr") {
          this.currProj = d.data;
          store.set("lastCurrProjId", d.data.id);
        } else if (item.status == "update") {
          this.updateProj(d.data);
        } else if (item.status == "del") {
          this.delProj(d.data);
        }
      } else if (d.type == "config-action") {
        if (item.status == "detail") {
          return this.showDetail("详情:" + d.data.label, clone(d.data));
        } else if (item.status == "update") {
          this.updateConfigRow(d.data);
        } else if (item.status == "del") {
          return this.delConfig(d.data.id);
        } else if (item.status == "up" || item.status == "down") {
          return this.onSortConfig(d.data, item.status);
        }
      }
    },
    async onSortConfig(configItem, action) {
      let cat = this.currProj.cats.find(
        (c) => c.cat_name == configItem.cat_name
      );
      let index = cat.configs.findIndex((c) => c.id == configItem.id);
      cat.configs.forEach((t, i) => {
        t.sort_id = i;
      });
      let item = cat.configs[index];
      if (action == "up") {
        if (item.sort_id == 0) {
          return this.showFail("已经在最顶了");
        }
        let preItem = cat.configs[index - 1];
        item.sort_id -= 1;
        preItem.sort_id += 1;
      } else {
        if (item.sort_id == cat.configs.length - 1) {
          return this.showFail("已经在最底了");
        }
        let nextItem = cat.configs[index + 1];
        item.sort_id += 1;
        nextItem.sort_id -= 1;
      }
      cat.configs
        .sort((t1, t2) => t1.sort_id - t2.sort_id)
        .forEach((t, i) => {
          t.sort_id = i;
        });
      // return;
      this.loading = true;
      this.showLoading(true);
      let okCount = 0,
        failCount = 0;
      for (let item of cat.configs) {
        let old = this.configs.find((c) => c.id == item.id);
        if (old.sort_id == item.sort_id) {
          continue;
        }
        let tmp = await dalConfig.update({ sort_id: item.sort_id }, item.id);
        if (tmp.msg == "ok") {
          okCount++;
        } else {
          failCount++;
        }
      }
      this.loading = false;
      this.showLoading(false);
      if (failCount == 0) {
        this.showOk("排序成功!");
      } else {
        this.alert(`成功:${okCount}，失败:${failCount}`, "排序完成");
      }
    },
    async onSaveFormContent() {
      let arr = [];
      let that = this;
      let error = [];
      this.currProj.cats.forEach((cat) => {
        cat.configs.forEach((t) => {
          let v = t.value;
          if (v !== null) {
            if (t.control_type == "number") {
              v = parseInt(v);
            }
            v = JSON.stringify({ v });
          }
          let tmp = that.configs.find((c) => c.id == t.id);
          if (!tmp || tmp.value == v) {
            return;
          }
          if (tmp.rule) {
            let vv = validatorRules.find((v) => v.label == tmp.rule);
            if (vv && !vv.fun(t.value)) {
              error.push(t.label + "：" + vv.error);
            }
          }
          arr.push({
            id: t.id,
            value: v,
          });
        });
      });
      if (error.length > 0) {
        console.log(error);
        return this.alert(error.join("\n"));
      }
      console.log({ arr });
      if (arr.length == 0) {
        return this.notify("warning", "没有改动，跳过");
      }
      // return;
      this.loading = true;
      this.showLoading(true);
      let okCount = 0,
        failCount = 0;
      for (let item of arr) {
        let tmp = await dalConfig.update({ value: item.value }, item.id);
        if (tmp.msg == "ok") {
          okCount++;
        } else {
          failCount++;
        }
      }
      this.loading = false;
      this.showLoading(false);
      this.alert(`成功:${okCount}，失败:${failCount}`, "保存完成");
      this.notifyCallbackUrl();
    },
    async notifyCallbackUrl() {
      let url = this.currProj.callback_url;
      if (!url || url.indexOf("http") != 0) {
        return { msg: "callback_url error" };
      }
      let data = this.currProj;
      let res = await dalProj.notify(data, url);
      console.log({ notifyCallbackUrl: res });
      return res;
    },
    onLogout() {
      dalUser.logout();
      this.showOk("退出成功");
      this.onShowLoginBox(true);
    },
  },
});
